﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Happy.Domain;
using Happy.Activities.Domain.WorkflowInstances;

namespace Happy.Activities.Domain.Workflows
{
    /// <summary>
    /// 工作流定义。
    /// </summary>
    public class Workflow : AggregateRoot<Guid>
    {
        /// <summary>
        /// 构造方法。
        /// </summary>
        public Workflow()
        {
            this.Activities = new List<Activity>();
            this.Routers = new List<Router>();
        }

        /// <summary>
        /// 活动集合。
        /// </summary>
        protected internal virtual ICollection<Activity> Activities { get; set; }

        /// <summary>
        /// 路由集合。
        /// </summary>
        protected internal virtual ICollection<Router> Routers { get; set; }

        /// <summary>
        /// 开始活动标识。
        /// </summary>
        public Guid StartActivityId { get; set; }

        /// <summary>
        /// 返回开始活动。
        /// </summary>
        public Activity GetStartActivity()
        {
            return this[this.StartActivityId];
        }

        /// <summary>
        /// 根据名字返回活动。
        /// </summary>
        public Activity this[string name]
        {
            get
            {
                return this.Activities.First(x => x.Name == name);
            }
        }

        /// <summary>
        /// 根据标识返回活动。
        /// </summary>
        public Activity this[Guid activityId]
        {
            get
            {
                return this.Activities.First(x => x.Id == activityId);
            }
        }

        /// <summary>
        /// 添加活动。
        /// </summary>
        public void AddActivity(Activity activity, bool isStartActivity = false)
        {
            activity.WorkflowId = this.Id;

            this.Activities.Add(activity);

            if (isStartActivity)
            {
                this.StartActivityId = activity.Id;
            }
        }

        /// <summary>
        /// 添加路由。
        /// </summary>
        public void AddRouter(Router router)
        {
            router.WorkflowId = this.Id;

            this.Routers.Add(router);
        }

        internal IEnumerable<Router> GetRoutersByToId(Guid toId)
        {
            return this.Routers.Where(x => x.ToId == toId).ToList();
        }

        internal IEnumerable<Router> GetRoutersByFromId(Guid fromId)
        {
            return this.Routers.Where(x => x.FromId == fromId).ToList();
        }

        internal void Run(WorkflowContext context)
        {
            context.WorkflowInstance.SetStateToRunning(context);

            var startActivity = this.GetStartActivity();

            var activityInstance = startActivity.CreateInstance(context);
            context.WorkflowInstance.AddActivityInstance(activityInstance);

            startActivity.Enter(context, activityInstance);
        }
    }
}
